090 Защита от сбоев
todo(d.maslennikov): сделать содержание
Стратегия защиты от аппаратных отказов
Как мы говорили ранее, аппаратные отказы могут являтся причинами сбоев только если мы сознательно выбрали от них не защищаться.
От аппаратных отказов есть только одна стратегия защиты, которая часто не так уж просто реализуется.
Для работы с аппаратными отказами нам необходимо иметь некоторый избыток апаратных ресурсов. В случае выхода из строя оборудования нам надо полагаться на этот избыток. То есть выводить из использования то железо, которое перестало работать корректно. Никаких других способов не существует. Но сущесвует масса способов реализации этой стратегии.
На самом верхнем уровне задача защиты разбивается на две подзадачи: детектировать отказ оборудования и выполнить переключение.
Детектировать проблемное железо можно вручную. В этом случае время реакции будет не менее 30 минут. Люди не могут реагировать быстрее. Это может подойти для некоторых сервисов. Но часто такое время реакции не будет устраивать.
Если нас это не устраивает, то придется детектировать такие отказы автоматически. Тогда время срабатывания защиты в зависимости от дизайна и реализации можно свести до миллисекунд. На практике в большинстве случаев легко и достаточно получить время реакции на уровне единиц секунд.
Как и во всех других случаях реализацию защиты от аппаратных проблем необходимо тестировать. Причем тестировать необходимо в обоих случаях. В первом случае мы тестируем, что инженеры знают как определять такие отказы и что делать в этом случае. Во втором случае тестируем наш код. Подобные тесты имеют смысл только если мы делаем их в продакшен. Естейственно сначала потренировавшись в искусственной среде.
Аппаратные сбои
Давайте рассмотрим физические причины сбоев. В основном это поломки оборудования. Современное оборудование очень надежно. Но нет ничего вечного. Чаще всего выходят из строя жесткие диски, но сломаться может любое оборудование: планки памяти, сетевые адаптеры, центральные процессоры и источники питания. Этот фактор будет с нами всегда. Поэтому проектировать процессы и реализацию сервиса надо обязательно с учетом аппаратных поломок.
Фактор поломок железа сильно усугубляется с масштабированием. Если у вас один сервер в надежном датацентре с хорошим питанием, то вероятность, что он простоит без поломок год очень велика. И можно даже проектировать сервисы без учета аппаратных поломок. Но, если у вас выросла нагрузка и у вас уже 2 сервера, то вероятность поломки увеличилась вдвое. Теперь представим, что мы выросли до большого бизнеса с большим числом клиентов и у нас 1000 серверов, на них 6000 дисков и к этому прилагается большое количество сетевого оборудования для коммутации всех этих серверов. Вероятность единичной поломки железа уже будет минимум в 1000 раз больше и на практике у вас будет множество аппаратных поломок оборудования в год. На таких объемах скорее всего каждую неделю будет несколько поломок.
Конечно современные сервисы устойчивы к аппаратным поломкам, то есть проектируются так, что выход из строя одного или даже нескольких серверов или части сетевой инфраструктуры не приводит к заметным последствиям, то есть к сбоям. Мы рассмотрим, как этого можно достичь далее, но идея состоит в том, что системы должны детектировать неполадки и переводить работу с поломанного оборудования на исправное автоматически.
Для того, чтобы справляться с аппаратными поломками наша инфраструктура должна обладать определенной избыточностью, то есть иметь больше серверов и сетевого оборудования, чем необходимо для работы.
Добавить некоторую избыточность по оборудованию довольно просто. А весь современный софт имеет архитектуру, которая призвана так или иначе бороться с такими отказами. Но тем не менее такие сбои очень часты. Дело в том, что команды эксплуатирующие сервис редко тестируют корректность работы средств защиты от подобных сбоев. Соответсвенно они, либо неправильно спроектированы, либо неправильно настроены, либо вообще ведут себя неожиданным образом, когда такая ситуация случается на практике. При этом часто сами команды не знают, что делать в случае сбоя.
Ситуация быстро меняется к лучшему, если мы сильно масштабировались и у нас много железа и такие сбои начинают случаться довольно часто. Таким образом сама жизнь помогает нам отладить поведение систем при отказе оборудования.
При правильной организации раюоты с надежностью мы не будем дожидаться такой ситуации, а начнем тестировать поведение систем защиты от аппаратных сбоев заранее. Сначала в специальном окружении, а потом и в продакшен. В данном случае нет ничего плохого в тестировании в продакшен, так как нам нужна работающая система защиты именно для продакшена и лучшая демострация ее хорошей работы может быть только ее работа в продакшен.
Если вы боитесь тестировать подобные средства защиты в продакшен окружении, это ваше бессознательное говорит, что на самом деле защита плохая и скорее всего не сработает. В хорошей системе вам должно быть абсолютно не страшно выдернуть питание или сетевой кабель из любого сервера в любое время.
Ошибка сотрудника при проведении плановых или других работ по обслуживанию систем
Заниматься обслуживанием должны разные инженеры, а не самые опытные — накапливать экспертизу.
- стихия или внешние техногенные факторы
- не защищаемся (форс-мажор)
- строим географически распределенные датацентры (размещаемся в клаудах) с возможностью переводить трафик между датацентрами целиком
- отказы оборудования
- не защищаемся (форс-мажор)
- ставим избыточное оборудование. Делаем ручное или автоматическое выведение сбойного оборудования из работы
- изменения в действиях пользователей в т.ч. рост нагрузки
- нужен процесс мониторинга достаточности ресурсов, планирование роста активности пользователей и планирования увеличения ресурсов
- переполнение
- правильная архитектура приложения (исключение возможности переполнения)
- мониторинг переполняемых ресурсов и процесс своевременного реагирования
- документирование вещей, которые могут переполниться
- изменения в действиях внешних систем
- процесс получения информации и реагирования на изменения во внешних системах
- альтернативные сценарии работы в случае недоступности внешних систем
- ошибка или недоработка в программном коде, архитектуре и т.п.
- синтетическое тестирование
- синтетическое тестирование на продакшен среде
- пробы
- снижение скорости разработки (code-freeze)
- альтернативные сценарии работы на зависимых системах
- тестирование на небольшом проценте пользователей
- фиче-флаги
- очень быстрый откат на предыдующую версию
- rolling update
- больший приоритет багфиксингу
- отказ от вендорского ПО
- консультации
- синтетическое тестирование
- ошибка или недоработка в процессах работы
- фиче-флаги
- rolling update
- изменение процесса
- усиление контроля
- ошибка сотрудника при проведении плановых или других работ по обслуживанию систем
- фиче-флаги
- rolling update
- сделать более интуитивные интерфейсы
- встроить защиту от опасных действий
- отработка действий администратором
- написание планов работ
- ошибка при использовании сервиса
- сделать более интуитивные интерфейсы
- встроить защиту от опасных действий
- отработка действий
- проблемная коммуникация между людьми
- встраивание документации в систему
- упрощение поиска документации
- экзамен на знание необходимой информации
- уменьшение количества уведомлений, согласований, "важных" писем
- обучение членов команды особенностям конкретной команды
- специальные каналы коммуникации с минимумом только очень важной информации
- подтверждение получения важной информации
- интерфейсы не требующие обучения (интуитивные)
- процессы исключающие ошибку (не требующие обучения)
- автоматизация наиболее проблемных стадий процессов (исключение их из обучения)
- прямая системная человеческая проблема (выгорание, депрессия, системная неудовлетворенность работой, конфликты и т.п.)
- TODO(d.maslennikov)
защиты от ошибок ("защита от дурака")
Ошибаются все. Очень важно защищать системы от ошибок разработчиков, тестировщиков, администраторов, операторов, пользователей и всех других людей, которые воздействуют на систему.
Есть несколько способов защищаться от ошибок на уровне системы.
1. Предупреждение о возможной ошибке
Примеры:
Подсветка ошибок в IDE, линтеры
Подтверждения опасных операций в UI. Не надо использовать одно и то же подтверждение для более и менее опасных операций. Или для частых и редких операций. Для частых и не очень опасных операций пользователь выработает привычку быстро и не думая подтверждать. И это сработатет во вред на опасной и редкой операции. Вместо этого можно выделять более опасные операции оформлением, делать таймеры на подтверждение (первые 5-10 секунд нельзя подтвердить) или заставлять вписать что-либо (например, идентификатор удаляемого объекта) в окно ввода для подтверждения.
2. Недопущение ошибок
Обязательные автотесты.
Проверка пользовательского ввода на валидность.
Обязательное прохождение линтеров.
Например, Gateway может не позвалять подать пользовательский трафик, до того, как пройдены тесты или до того, как прогреты кеши. А лучше самостоятельно давать сигнал на тестирование или прогрев кешей при попытке подать трафик.
3. Нечувствительность к ошибкам
Когда система в принципе задизайнена так, что ошибки не приносят большого вреда.
Например, система релизится роллинг апдейтом. В случае ошибки в ПО такая ошибка обнаруживается на ранней стадии и только малое количество клиентов затрагивается.
4. Учения, отработка действий
В отработанных действиях ошибаются реже.
Wheel-of-misfortune.
DiRT
5. Четкий план действий
Больше подходит для релизов.